import axios from 'axios'
import { getToken } from '@/utils/auth'
import { Message } from 'element-ui'

// 以post请求为例
/**
 *
 * @param {String} url  请求地址
 * @param {Object} params  请求参数
 * @param {String} fileName 文件名
 * @param {String} fileType  下载的文件类型
 * @param {String} callBack  下载完成后的回调
 */
export default function downLoad(url, params, fileName, fileType = 'Excel', callBack, contentType = 'application/json') {
    // api_source.url为请求地址前缀，以实际项目为准
    axios
        .post(window.api_source.url + url, params, {
            headers: { token: getToken(), 'Content-Type': contentType },
            // 这里设置为blob或者arraybuffer都可以
            responseType: 'blob'
            // responseType: 'arraybuffer'
        })
        .then(res => {
            // 后端报错时返回的是json，进行文件读取，报错不下载
            if (res.data.type === 'application/json') {
                const reader = new FileReader()
                reader.readAsText(res.data, 'utf-8')
                reader.onload = () => {
                    const data = JSON.parse(reader.result)
                    Message.error(data.message)
                }
                return
            }
            handleResult(fileName, fileType, res)
        }).catch(() => {
            Message({
                type: 'error',
                message: '导出失败，请稍后再试！'
            })
        }).finally(() => {
            callBack && callBack()
        })
}

export const downLoadGet = (url, params, fileName, fileType = 'Excel', callBack) => {
    console.log('token', getToken())
    // api_source.url为请求地址前缀，以实际项目为准
    axios
        .get(window.api_source.url + url, {
            headers: { token: getToken(), 'Content-Type': 'application/json' },
            // 这里设置为blob或者arraybuffer都可以
            responseType: 'blob',
            params
        })
        .then(res => {
            // 后端报错时返回的是json，进行文件读取，报错不下载
            if (res.data.type === 'application/json') {
                const reader = new FileReader()
                reader.readAsText(res.data, 'utf-8')
                reader.onload = () => {
                    const data = JSON.parse(reader.result)
                    Message.error(data.message)
                }
                return
            }
            handleResult(fileName, fileType, res)
        }).catch(error => {
            const { status } = error.response
            if (status !== 200) {
                Message({
                    type: 'error',
                    message: '导出失败，请稍后再试！'
                })
            }
        }).finally(() => {
            callBack && callBack()
        })
}

// 处理返回文件流
export const handleResult = (customfileName, fileType, res) => {
    // 首先，尝试从响应头中获取文件名
    let fileName = customfileName
    if (!fileName) {
        const contentDisposition = res.headers['content-disposition']
        if (contentDisposition) {
            // 解析Content-Disposition头部，通常格式为 'attachment; filename*=UTF-8''filename'
            const match = /filename\*?=(["']?)([^"']*)\1/i.exec(contentDisposition)
            if (match) {
                fileName = decodeURIComponent(match[2])
                // console.log('fileName', fileName)
            }
        }
    }
    // 各种文件格式配置
    const contentType = {
        Excel: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8',
        Zip: 'application/zip;charset=UTF-8',
        Word: 'application/msword;charset=UTF-8',
        Html: 'text/html;charset=UTF-8',
        Txt: 'text/plain;charset=utf-8'
    }
    const blob = new Blob([res.data], {
        type: contentType[fileType]
    })

    // URL.createObjectURL()根据传入的参数创建一个指向该参数对象的URL
    const objectUrl = URL.createObjectURL(blob)

    // 可以直接用window.open()下载，但是没法自定义文件名称
    // window.open(objectUrl)

    // 模拟a标签点击下载文件
    const a = document.createElement('a')
    a.href = objectUrl
    a.download = fileName
    // a标签添加到body中，然后模拟点击，火狐浏览器需要把a标签添加到body中点击才有效，谷歌可以省略appendChild这一步
    document.body.appendChild(a)
    a.click()
    // 把a标签删除，减少dom节点冗余
    document.body.removeChild(a)

    // URL.revokeObjectURL()方法会释放一个通过URL.createObjectURL()创建的对象URL
    URL.revokeObjectURL(objectUrl)
}

// 最后在需要使用的地方import引入后调用downLoad()即可
